package com.farm.kaiping.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import com.farm.common.security.SecurityUtils;
import com.farm.kaiping.entity.SysRegion;
import com.farm.kaiping.po.SysRegionPO;
import com.farm.kaiping.mapper.SysRegionMapper;
import com.farm.kaiping.service.SysRegionService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.farm.common.util.StringRange;
import com.farm.kaiping.vo.SysRegionVO;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 行政区划(SysRegion)表服务实现类
 *
 * @author zhuhui
 * @since 2024-11-26 22:58:21
 */
@Service
@Slf4j
@AllArgsConstructor
public class SysRegionServiceImpl extends ServiceImpl<SysRegionMapper, SysRegion> implements SysRegionService {
    
	private LambdaQueryWrapper<SysRegion> generateQueryWrapper(SysRegionPO sysRegionPO){
		LambdaQueryWrapper<SysRegion> queryWrapper = new LambdaQueryWrapper<>();
		// 行政区划id
		queryWrapper.eq(ObjectUtil.isNotEmpty(sysRegionPO.getId()), SysRegion::getId, sysRegionPO.getId());
		queryWrapper.in(ObjectUtil.isNotEmpty(sysRegionPO.getIdList()), SysRegion::getId, sysRegionPO.getIdList());
		// 名称
		queryWrapper.like(ObjectUtil.isNotEmpty(sysRegionPO.getRegionName()), SysRegion::getRegionName, sysRegionPO.getRegionName());
		// 行政区划编码 12位编码（省2位，市2位，区2位，街道3位，社区3位）
		queryWrapper.like(ObjectUtil.isNotEmpty(sysRegionPO.getRegionCode()), SysRegion::getRegionCode, sysRegionPO.getRegionCode());
		// 国家统一行政代码
		queryWrapper.like(ObjectUtil.isNotEmpty(sysRegionPO.getNationalCode()), SysRegion::getNationalCode, sysRegionPO.getNationalCode());
		// 层级（1省级2市级3区级4街道级5社区级）
		queryWrapper.eq(ObjectUtil.isNotEmpty(sysRegionPO.getRegionGrade()), SysRegion::getRegionGrade, sysRegionPO.getRegionGrade());
		queryWrapper.in(ObjectUtil.isNotEmpty(sysRegionPO.getRegionGradeList()), SysRegion::getRegionGrade, sysRegionPO.getRegionGradeList());
		// 父级id
		queryWrapper.eq(ObjectUtil.isNotEmpty(sysRegionPO.getParentId()), SysRegion::getParentId, sysRegionPO.getParentId());
		queryWrapper.in(ObjectUtil.isNotEmpty(sysRegionPO.getParentIdList()), SysRegion::getParentId, sysRegionPO.getParentIdList());
		// 行政区划路径Id
		queryWrapper.apply(ObjectUtil.isNotEmpty(sysRegionPO.getPathIds()),"FIND_IN_SET({0},path_ids)", sysRegionPO.getPathIds());
		queryWrapper.eq(ObjectUtil.isNotEmpty(sysRegionPO.getPathId()), SysRegion::getPathIds, sysRegionPO.getPathId());
		if (ObjectUtil.isNotEmpty(sysRegionPO.getPathIdList())) {
			queryWrapper.and(param -> {
				param.apply("FIND_IN_SET({0},path_ids)", sysRegionPO.getPathIdList().get(0));
				if (sysRegionPO.getPathIdList().size() > 1) {
					for (int i = 1; i < sysRegionPO.getPathIdList().size(); i++) {
						param.or().apply("FIND_IN_SET({0},path_ids)", sysRegionPO.getPathIdList().get(i));
					}
				}
			});
		}
		// 行政区划路径名称
		queryWrapper.apply(ObjectUtil.isNotEmpty(sysRegionPO.getPathNames()),"FIND_IN_SET({0},path_ids)", sysRegionPO.getPathNames());
		queryWrapper.eq(ObjectUtil.isNotEmpty(sysRegionPO.getPathName()), SysRegion::getPathNames, sysRegionPO.getPathName());
		if (ObjectUtil.isNotEmpty(sysRegionPO.getPathNameList())) {
			queryWrapper.and(param -> {
				param.apply("FIND_IN_SET({0},path_names)", sysRegionPO.getPathNameList().get(0));
				if (sysRegionPO.getPathNameList().size() > 1) {
					for (int i = 1; i < sysRegionPO.getPathNameList().size(); i++) {
						param.or().apply("FIND_IN_SET({0},path_names)", sysRegionPO.getPathNameList().get(i));
					}
				}
			});
		}
		// 是否删除(0否1是)
		queryWrapper.eq(ObjectUtil.isNotEmpty(sysRegionPO.getDelFlag()), SysRegion::getDelFlag, sysRegionPO.getDelFlag());
        queryWrapper.eq(ObjectUtil.isEmpty(sysRegionPO.getDelFlag()), SysRegion::getDelFlag, 0);
		// 新增时间
		queryWrapper.eq(ObjectUtil.isNotEmpty(sysRegionPO.getCreateTime()), SysRegion::getCreateTime, sysRegionPO.getCreateTime());
		// 创建人ID
		queryWrapper.eq(ObjectUtil.isNotEmpty(sysRegionPO.getCreateUserId()), SysRegion::getCreateUserId, sysRegionPO.getCreateUserId());
		// 创建人姓名
		queryWrapper.like(ObjectUtil.isNotEmpty(sysRegionPO.getCreateUserName()), SysRegion::getCreateUserName, sysRegionPO.getCreateUserName());
		// 更新时间
		queryWrapper.eq(ObjectUtil.isNotEmpty(sysRegionPO.getUpdateTime()), SysRegion::getUpdateTime, sysRegionPO.getUpdateTime());
		// 更新人ID
		queryWrapper.eq(ObjectUtil.isNotEmpty(sysRegionPO.getUpdateUserId()), SysRegion::getUpdateUserId, sysRegionPO.getUpdateUserId());
		// 更新人姓名
		queryWrapper.like(ObjectUtil.isNotEmpty(sysRegionPO.getUpdateUserName()), SysRegion::getUpdateUserName, sysRegionPO.getUpdateUserName());
		// 租户ID
		queryWrapper.eq(ObjectUtil.isNotEmpty(sysRegionPO.getTenantId()), SysRegion::getTenantId, sysRegionPO.getTenantId());
		// 创建时间时间区间查询
		queryWrapper.ge(ObjectUtil.isNotEmpty(StringRange.getOne(sysRegionPO.getCreateTimeBetween(),0)), SysRegion::getCreateTime,StringRange.getOne(sysRegionPO.getCreateTimeBetween(),0));
		queryWrapper.le(ObjectUtil.isNotEmpty(StringRange.getOne(sysRegionPO.getCreateTimeBetween(),1)), SysRegion::getCreateTime,StringRange.getOne(sysRegionPO.getCreateTimeBetween(),1));
		// 更新时间时间区间查询
		queryWrapper.ge(ObjectUtil.isNotEmpty(StringRange.getOne(sysRegionPO.getUpdateTimeBetween(),0)), SysRegion::getUpdateTime,StringRange.getOne(sysRegionPO.getUpdateTimeBetween(),0));
		queryWrapper.le(ObjectUtil.isNotEmpty(StringRange.getOne(sysRegionPO.getUpdateTimeBetween(),1)), SysRegion::getUpdateTime,StringRange.getOne(sysRegionPO.getUpdateTimeBetween(),1));

		queryWrapper.orderByAsc(SysRegion::getRegionCode);
		return queryWrapper;
	}

	 /**
	  * @describe 分页查询行政区划
	  * @author zhuhui
	  * @date 2024-11-26 22:58:21
	  */
	@Override
	public Page<SysRegion> getSysRegionPage(Page page, SysRegionPO sysRegionPO){
		LambdaQueryWrapper<SysRegion> queryWrapper = this.generateQueryWrapper(sysRegionPO);
        return this.baseMapper.selectPage(page, queryWrapper);
	}
	
	/**
     * @describe 查询行政区划list
     * @author  zhuhui
     * @date  2024-11-26 22:58:21
     */
	@Override
	public List<SysRegion> getSysRegionList(SysRegionPO sysRegionPO){
		LambdaQueryWrapper<SysRegion> queryWrapper = this.generateQueryWrapper(sysRegionPO);
        return this.baseMapper.selectList(queryWrapper);
	}

	@Override
	public List<SysRegionVO> getSysRegionSimpleList(SysRegionPO sysRegionPO) {
		LambdaQueryWrapper<SysRegion> queryWrapper = this.generateQueryWrapper(sysRegionPO);
		queryWrapper.select(
			SysRegion::getId,
			SysRegion::getRegionName,
			SysRegion::getRegionCode,
			SysRegion::getNationalCode,
			SysRegion::getRegionGrade,
			SysRegion::getParentId,
			SysRegion::getPathIds,
			SysRegion::getPathNames
		);
		return this.baseMapper.selectSimpleList(queryWrapper);
	}

	/**
     * @describe 获取一条数据 行政区划
     * @author  zhuhui
     * @date  2024-11-26 22:58:21
     */
	@Override
	public SysRegion getSysRegion(SysRegionPO sysRegionPO){
		LambdaQueryWrapper<SysRegion> queryWrapper = this.generateQueryWrapper(sysRegionPO);
        queryWrapper.last("LIMIT 1");
        return this.baseMapper.selectOne(queryWrapper);
	}

    /**
     * @describe 新增行政区划
     * @author  zhuhui
     * @date  2024-11-26 22:58:21
     */
	@Override
	public Integer saveSysRegion(SysRegionPO sysRegionPO) {
		if (ObjectUtil.isEmpty(sysRegionPO.getRegionName())){
			throw new RuntimeException("名称为空");
		}
		if (ObjectUtil.isEmpty(sysRegionPO.getRegionCode())){
			throw new RuntimeException("编码为空");
		}
		if (ObjectUtil.isEmpty(sysRegionPO.getNationalCode())){
			throw new RuntimeException("国家统一代码为空");
		}
		if (ObjectUtil.isEmpty(sysRegionPO.getParentId())){
			throw new RuntimeException("父级id为空");
		}
        sysRegionPO.setDelFlag(0);
		sysRegionPO.setTenantId(SecurityUtils.getUser().getTenantId());// 租户ID
		sysRegionPO.setCreateTime(LocalDateTime.now());
		sysRegionPO.setCreateUserId(SecurityUtils.getUser().getUserId());// 创建人
		sysRegionPO.setCreateUserName(SecurityUtils.getUser().getRealName());// 创建人
		sysRegionPO.setUpdateTime(LocalDateTime.now());
		SysRegion sysRegion = BeanUtil.copyProperties(sysRegionPO, SysRegion.class);
		this.save(sysRegion);
		return sysRegion.getId();
	}

	/**
     * @describe 修改行政区划
     * @author  zhuhui
     * @date  2024-11-26 22:58:21
     */
	@Override
	public String updateSysRegion(SysRegionPO sysRegionPO) {
		if (ObjectUtil.isEmpty(sysRegionPO.getId())) {
			throw new RuntimeException("id为空");
		}
		if (ObjectUtil.isEmpty(sysRegionPO.getRegionName())){
			throw new RuntimeException("名称为空");
		}
		if (ObjectUtil.isEmpty(sysRegionPO.getRegionCode())){
			throw new RuntimeException("编码为空");
		}
		if (ObjectUtil.isEmpty(sysRegionPO.getNationalCode())){
			throw new RuntimeException("国家统一代码为空");
		}
		if (ObjectUtil.isEmpty(sysRegionPO.getParentId())){
			throw new RuntimeException("父级id为空");
		}

		sysRegionPO.setUpdateUserId(SecurityUtils.getUser().getUserId());// 更新人
		sysRegionPO.setUpdateUserName(SecurityUtils.getUser().getRealName());// 更新人
		sysRegionPO.setUpdateTime(LocalDateTime.now());
		SysRegion sysRegion = BeanUtil.copyProperties(sysRegionPO, SysRegion.class);
		this.updateById(sysRegion);
		return "修改成功";
	}

	/**
     * @describe 通过id删除行政区划
     * @author  zhuhui
     * @date  2024-11-26 22:58:21
     */
	@Override
	public String removeSysRegion(SysRegionPO sysRegionPO) {
		if (ObjectUtil.isEmpty(sysRegionPO.getBatchDel())) {
			throw new RuntimeException("删除数据未选择");
		}
		LambdaUpdateWrapper<SysRegion> removeWrapper = new LambdaUpdateWrapper<>();
		removeWrapper.in(SysRegion::getId, sysRegionPO.getBatchDel());
		removeWrapper.set(SysRegion::getDelFlag,1);
		removeWrapper.set(SysRegion::getUpdateUserId,SecurityUtils.getUser().getUserId());// 更新人
		removeWrapper.set(SysRegion::getUpdateUserName,SecurityUtils.getUser().getRealName());// 更新人
		removeWrapper.set(SysRegion::getUpdateTime,LocalDateTime.now());

		this.update(removeWrapper);
		return "删除成功";
	}

	@Override
	public List<SysRegionVO> treeSysRegion(SysRegionPO sysRegionPO) {
		sysRegionPO.setRootId(ObjectUtil.isEmpty(sysRegionPO.getRootId())?0:sysRegionPO.getRootId());
		List<SysRegionVO> sysRegionList = this.getSysRegionSimpleList(sysRegionPO);
		List<SysRegionVO> collect = sysRegionList.stream()
				.filter(sysRegion -> ObjectUtil.equal(sysRegion.getParentId(),sysRegionPO.getRootId()))
				.collect(Collectors.toList());
		for (SysRegionVO sysRegion : collect) {
			sysRegion.setChildren(buildChildren(sysRegion.getId(),sysRegionList));
		}
		return collect;
	}

	private static List<SysRegionVO> buildChildren(Integer id, List<SysRegionVO> sysRegionList) {
		List<SysRegionVO> children = new ArrayList<>();
		for (SysRegionVO sysRegion : sysRegionList) {
			if (ObjectUtil.isEmpty(sysRegion.getParentId()) || ObjectUtil.equal(sysRegion.getParentId(),0)){
				continue;
			}
			if (sysRegion.getParentId().equals(id)){
				children.add(sysRegion);
			}
		}
		for (SysRegionVO child : children) {
			child.setChildren(buildChildren(child.getId(),sysRegionList));
		}
		return children;
	}

	// TODO 项目启动时将 行政区划写入redis 或者提供接口刷新redis
	// TODO 名称转ID(redis中获取数据)
	// TODO ID转名称(redis中获取数据)

}

